<?php
declare (strict_types=1);

namespace app\user\logic\teacher\admin;

use app\admin\logic\system\Log;
use app\common\event\subscribes\notify\Notify as NotifyEvent;
use app\common\exception\LogicException;
use app\user\logic\user\admin\Account;
use app\user\model\teacher\admin\Teacher as TeacherModel;
use think\facade\Db;
use think\facade\Event;

class Teacher extends TeacherModel
{

    /**
     * 讲师列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-06-03
     *
     * @param    [type]                         $map [description]
     * @return   [type]                                [description]
     */
    public function getList(array $map = [])
    {
        return $this->with(['level', 'user', 'school'])->where($map)->order('update_time', 'DESC')->paginate($this->getListRows());
    }

    /**
     * 讲师待审核列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-05-12
     *
     * @return   [type]                         [description]
     */
    public function getWaitingList(array $map = [])
    {
        return $this->withoutGlobalScope(['mhm'])->scope('waiting')->with(['user'])->where($map)->order('create_time')->paginate($this->getListRows());
    }

    /**
     * 创建讲师
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-17
     */
    public function createTeacher(array $data)
    {
        $check = [
            'fullcategorypath' => $data['cates'],
            'category'         => $data['cates'],
            'level_id'         => $data['level_id'],
            'mhm_id'           => $data['mhm_id'] ?? request()->mhm_id,
            'status'           => $data['status'] ?? 1,
            'info'             => $data['info'] ?? '',
            'IDcard'           => $data['IDcard'] ?? '',
            'IDcard_positive'  => $data['IDcard_positive'] ?? 0,
            'IDcard_side'      => $data['IDcard_side'] ?? 0,
            'certification'    => $data['certification'] ?? 0,
            'user_phone'       => $data['user_phone'],
            'is_audit'         => $data['is_audit'] ?? 1,
            'best_sort'        => $data['best_sort'] ?? 999,
        ];
        // 验证数据
        $this->getValidate()->scene('create')->failException()->check($check);

        $user_id = 0;

        // 是否已经注册过学员
        // $user = app(Account::class)->withoutGlobalScope(['mhm'])->removeOption('soft_delete')->where('phone', $data['user_phone'])->findOrEmpty();
        $user = app(Account::class)->removeOption('soft_delete')->where('phone', $data['user_phone'])->findOrEmpty();
        if ($user->getAttr('delete_time')) {
            // 真实删除
            $user->force()->delete();
        } else if (!$user->isEmpty()) {
            $user_id = $user->getAttr('id');
            // 是否已经绑定过机构
            if ($this->where('user_id', $user_id)->value('id')) {
                throw new LogicException('当前手机号绑定的用户已成为讲师，不可再次创建');
            }
            // 是否是当前机构的学员
            if ($user->getAttr('mhm_id') != $check['mhm_id']) {
                throw new LogicException('当前手机号绑定的用户不属于该机构');
            }
        }

        try {
            $code = 0;
            if (!$user_id) {
                // 创建学员
                $user = [
                    'phone'    => $data['user_phone'],
                    'password' => md5(substr($data['user_phone'], -6)),
                    'mhm_id'   => $data['mhm_id'] ?? request()->mhm_id
                ];

                $user    = app(Account::class)->addUser($user);
                $user_id = $user->getAttr('id');

                $code = 1;
            }

            $check['user_id'] = $user_id;

            unset($check['user_phone']);

            // 新建机构
            if (!$this->save($check)) {
                throw new LogicException('新建失败');
            }

            $this->commit();

            // 清理推荐课程缓存
            cache('recommend_teacher', null);

            if (file_exists('home_pc.txt')) unlink('home_pc.txt');
            if (file_exists('home_ot.txt')) unlink('home_ot.txt');

            return $code;
        } catch (LogicException $e) {
            $this->rollback();
            throw $e;
        } catch (\Exception $e) {
            $this->rollback();
            throw new LogicException('创建用户账号失败');

        }
    }

    /**
     * 编辑讲师
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-17
     *
     * @param array $data [接口传入信息]
     * @return   array      $user  [编辑的用户信息]
     */
    public function editTeacher(int $id, array $data)
    {

        $teacher = $this->where('id', $id)->findOrFail();
        // 取得验证器
        $this->getValidate()->scene('edit')->failException()->check($data);

        $teacher->fullcategorypath = $data['cates'];
        $teacher->category         = $data['cates'];
        $teacher->level_id         = $data['level_id'];
        $teacher->mhm_id           = $data['mhm_id'] ?? request()->mhm_id;
        $teacher->info             = $data['info'] ?? '';
        $teacher->status           = $data['status'] ?? 1;
        $teacher->IDcard           = $data['IDcard'] ?? '';
        $teacher->IDcard_positive  = $data['IDcard_positive'] ?? 0;
        $teacher->IDcard_side      = $data['IDcard_side'] ?? 0;
        $teacher->certification    = $data['certification'] ?? 0;
        $teacher->is_audit         = $data['is_audit'] ?? 1;
        $teacher->best_sort        = $data['best_sort'] ?? 999;

        if (!$teacher->save()) {
            throw new LogicException('编辑失败');
        }

        // 清理推荐课程缓存
        cache('recommend_teacher', null);

        if (file_exists('home_pc.txt')) unlink('home_pc.txt');
        if (file_exists('home_ot.txt')) unlink('home_ot.txt');

        return $teacher;
    }

    /**
     * 获取讲师名称
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-06-03
     *
     * @param    [type]                         $id [description]
     * @return   [type]                             [description]
     */
    public function getTeacherNameById($id)
    {
        return $this->where('id', $id)->with(['user'])->findOrEmpty()->getAttr('teacher_name');
    }

    /**
     * 获取讲师选项
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-06-03
     *
     * @return   [type]                         [description]
     */
    public function getSelectOptions(int $mhm_id = 1)
    {
        $data    = $this->scope('status')->where('mhm_id', $mhm_id)->with(['user'])->select();
        $options = [];

        foreach ($data as $item) {
            $options[] = [
                'value' => $item->getAttr('id'),
                'title' => $item->getAttr('teacher_name'),
            ];
        }

        return $options;
    }

    /**
     * 编辑指定字段
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/9/28
     *
     * @param $id
     * @param $field
     * @param $value
     * @return array|\think\Model
     */
    public function editField($id, $field, $value)
    {
        // 信息
        $teacher = $this->findOrFail($id);

        $teacher->$field = $value;

        if (!$teacher->save()) {
            throw new LogicException("更新失败");
        }

        // 清理推荐课程缓存
        cache('recommend_teacher', null);

        // 返回值
        return $teacher;
    }

    /**
     * 删除
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-05-29
     *
     * @param int $id [description]
     * @return   [type]                             [description]
     */
    public function deleteTeacher(int $id)
    {
        $teacher = $this->where('id', $id)->findOrFail();

        if (!$teacher->delete()) {
            throw new LogicException('删除失败');

        }
        // 清理推荐课程缓存
        cache('recommend_teacher', null);

        if (file_exists('home_pc.txt')) unlink('home_pc.txt');
        if (file_exists('home_ot.txt')) unlink('home_ot.txt');
    }

    /**
     * 审核操作
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-05-29
     *
     * @param int $id [description]
     * @return   [type]                             [description]
     */
    public function doExamine(int $id, array $data)
    {
        $teacher = $this->with(['user'])->where('id', $id)->where('status', 2)->findOrFail();

        Db::startTrans();
        try {
            $status = $data['status'] === 1 ? 1 : 3;
            // 审核通过
            $teacher->status = $status;

            if ($teacher->save()) {
                // 消息内容
                $info = $status === 1 ? '讲师申请审核已通过' : '讲师申请审核未通过，原因：' . $data['reason'];
                $var  = [
                    'user_name' => app(Account::class)->getUserNickName($teacher->user_id),
                    'reason'    => $data['reason'] ?? ""
                ];

                // 日志记录
                app(TeacherLog::class)->writeLog($id, $info, 0);

                // 通知消息
                // Event::subscribe(NotifySubscribes::class);
                // Event::trigger('TeacherExamine', ['user_id' => $teacher->user_id, 'content' => $info]);

                // 通知消息
                Event::subscribe(NotifyEvent::class);
                Event::trigger('Notify', [
                    'user' => $teacher->user_id,
                    'type' => 'system_notify',
                    'key'  => $status === 1 ? 'teacher_auth_pass' : 'teacher_auth_reject',
                    'var'  => $var,
                ]);
                if ($status === 1) {
                    Log::write('讲师审核通过【' . $teacher->teacher_name . '/' . $teacher->IDcard . '】', 'teacher', 'update', true);
                } else {
                    Log::write('讲师审核驳回【' . $teacher->teacher_name . '/' . $teacher->IDcard . '】', 'teacher', 'update', true);
                }

                // 提交
                Db::commit();

                return true;
            }

            throw new LogicException('操作失败');

        } catch (LogicException $e) {

            Db::rollback();
            throw $e;

        } catch (\Exception $e) {

            Db::rollback();
            throw new LogicException('操作失败');

        }

        // 清理推荐课程缓存
        cache('recommend_teacher', null);

        if (file_exists('home_pc.txt')) unlink('home_pc.txt');
        if (file_exists('home_ot.txt')) unlink('home_ot.txt');
    }

    /**
     * 搜索讲师
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-07-06
     *
     * @param string $keyword [description]
     * @return   [type]                                  [description]
     */
    public function getSearchList(string $keyword = '', $limit = 12, array $map = [])
    {
        $builder = $this->withoutGlobalScope(['mhm'])->with(['user'])->withJoin('user');
        if ($keyword != '') {
            $builder->where(function ($query) use ($keyword) {
                $query
                    ->where('user.nick_name', 'like', '%' . $keyword . '%')
                    ->whereOr('user.phone', 'like', '%' . $keyword . '%')
                    ->whereOr('__TABLE__.IDcard', 'like', '%' . $keyword . '%');
            });
        }

        return $builder
            ->where($map)
            ->field([
                '__TABLE__.id' => 'value',
                '__TABLE__.from',
                '__TABLE__.status',
                '__TABLE__.user_id'
            ])
            ->limit($limit)
            ->order('__TABLE__.update_time', 'DESC')
            ->select()
            ->each(function ($item) {
                $item->title = $item->teacher_name;
            });
    }

    /**
     * 批量更新数据
     *
     * @param array  $ids
     * @param string $field
     * @param        $value
     */
    public function batchUpdated(array $ids, string $field, $value)
    {
        $ret = TeacherModel::update([$field => $value], [['id', 'in', $ids]]);
        if (!$ret) {
            throw new LogicException('批量操作失败');
        }
    }

    /**
     * 批量删除
     * Author: Martinsun <syh@sunyonghong.com>
     * Date: 2020/10/16
     *
     * @param $ids
     */
    public function deleteTeachers($ids): void
    {
        $list = $this->whereIn('id', $ids)->select();
        if (!$list->delete()) {
            throw new LogicException('操作失败');
        }

        // 清理推荐课程缓存
        cache('recommend_teacher', null);

        if (file_exists('home_pc.txt')) unlink('home_pc.txt');
        if (file_exists('home_ot.txt')) unlink('home_ot.txt');
    }

    /**
     * 根据条件获取讲师列表
     *
     * @param string $keyword
     * @param int    $limit
     * @param array  $map
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getTeacherList(string $keyword = '', $limit = 12, array $map = [])
    {
        $builder = $this->withoutGlobalScope(['mhm'])->with(['user'])->join('user', 'user.id = __TABLE__.user_id');
        if ($keyword != '') {
            $builder->where(function ($query) use ($keyword) {
                $query
                    ->where('user.nick_name', 'like', '%' . $keyword . '%')
                    ->whereOr('user.phone', 'like', '%' . $keyword . '%')
                    ->whereOr('__TABLE__.IDcard', 'like', '%' . $keyword . '%');
            });
        }

        return $builder
            ->where($map)
            ->field([
                '__TABLE__.id' => 'value',
                '__TABLE__.from',
                '__TABLE__.status',
                '__TABLE__.user_id'
            ])
            ->order('__TABLE__.update_time', 'DESC')
            ->paginate($limit)
            ->each(function ($item) {
                $item->title = $item->teacher_name;
                // $item->avatar_url = '';
            });
    }

    /**
     * 获取讲师详情
     *
     * @param array $ids
     * @return Teacher[]|array|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getTeachers(array $ids)
    {
        return $this
            ->whereIn('id', $ids)
            ->with(['user', 'level'])
            // ->join('user', 'user.id = __TABLE__.user_id')
            ->field([
                '__TABLE__.id' => 'value',
                '__TABLE__.from',
                '__TABLE__.status',
                '__TABLE__.user_id',
                '__TABLE__.level_id'
            ])
            ->order('__TABLE__.update_time', 'DESC')
            ->select()
            ->each(function ($item) {
                $item->title = $item->teacher_name;
            });
    }

}
